#pragma once
#include <vector>
#include <iostream>
#include <cassert>
#define BUFFER_DEFAULT_SIZE (1 * 1024 * 1024)
#define BUFFER_INCREMENT_SIZE (1 * 1024 * 1024)  // 后期线性扩容
#define BUFFER_THRESHOLD_SIZE (10 * 1024 * 1024) // 小于它就成倍扩容
class Buffer
{

public:
    Buffer() : _rd_idx(0), _wr_idx(0), _buff(BUFFER_DEFAULT_SIZE) {}
    bool Empty() { return _wr_idx == _rd_idx; }
    size_t Rd_size() { return _wr_idx - _rd_idx; }
    size_t Wr_size() { return _buff.size() - _wr_idx; }

    void Reset() { _wr_idx = _rd_idx = 0; }

    void Pop(size_t len)
    {
        _rd_idx += len;
        assert(_rd_idx  <= _wr_idx);
    }
    void Push(const char *data, size_t len)
    {
        // assert(len<=Wr_size());
        Increase_cap(len); // 内部自己处理
        std::copy(data, data + len, &_buff[_wr_idx]);
         _wr_idx+=len;
    }
    const char *R_begin()
    {
        return &_buff[_rd_idx];
    }

    void Swap(Buffer &buff)
    {
        _buff.swap(buff._buff);
        std::swap(_rd_idx, buff._rd_idx);
        std::swap(_wr_idx, buff._wr_idx);
    }

private:
    void Increase_cap(size_t len)
    {
         if(len<=Wr_size()) return ;//足够写空间不操作
        size_t new_capacity = 0;
        //此版本下无论安全还是非安全模式下异步日志都不可能扩容--->可以换种方式应用但是
        //数组模拟的缓冲区情况安全：一定长度只要读慢写满就卡死 非安全-->利用时间（缓冲区交换清空）来模拟增长的空间
        //std::cout<<"扩容"<<std::endl;
        if (_buff.size() < BUFFER_THRESHOLD_SIZE)
            new_capacity = _buff.size() * 2 + len;
        else
            new_capacity = _buff.size() + BUFFER_INCREMENT_SIZE + len;
        _buff.resize(new_capacity);
    }
    std::vector<char> _buff;
    size_t _wr_idx;
    size_t _rd_idx;
};